#ifndef __HET_CHATGPT_h__
#define __HET_CHATGPT_h__

#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>

#include "rk_debug.h"
#include "rk_defines.h"
#include "rk_mpi_adec.h"
#include "rk_mpi_aenc.h"
#include "rk_mpi_ai.h"
#include "rk_mpi_ao.h"
#include "rk_mpi_avs.h"
#include "rk_mpi_cal.h"
#include "rk_mpi_ivs.h"
#include "rk_mpi_mb.h"
#include "rk_mpi_rgn.h"
#include "rk_mpi_sys.h"
#include "rk_mpi_tde.h"
#include "rk_mpi_vdec.h"
#include "rk_mpi_venc.h"
#include "rk_mpi_vi.h"
#include "rk_mpi_vo.h"
#include "rk_mpi_vpss.h"
#include <rk_aiq_user_api2_camgroup.h>
#include <rk_aiq_user_api2_imgproc.h>
#include <rk_aiq_user_api2_sysctl.h>

#include "rk_mpi_amix.h"
#include "mp3dec.h"
#include "rkdemuxer.h"
#include <curl/curl.h>

#ifdef ROCKIVA
#include "rockiva/rockiva_ba_api.h"
#include "rockiva/rockiva_common.h"
#include "rockiva/rockiva_det_api.h"
#include "rockiva/rockiva_face_api.h"
#include "rockiva/rockiva_image.h"
#endif


#include "clog.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************
    macro define
*******************************************************/
#define RKAIQ
#define RK_ALIGN(x, a) (((x) + (a)-1) & ~((a)-1))
#define RK_ALIGN_2(x) RK_ALIGN(x, 2)
#define RK_ALIGN_16(x) RK_ALIGN(x, 16)
#define RK_ALIGN_32(x) RK_ALIGN(x, 32)
typedef void *(*Thread_Func)(void *param);


#define AO_CHN_ID 0
#define AO_DEV_ID 0
#define AI_CHN_ID 0
#define AI_DEV_ID 0
#define AGENT_STRLEN_MIN 3
/*******************************************************
    enum define
*******************************************************/
typedef enum rk_CODEC_TYPE_E {
	RK_CODEC_TYPE_NONE = -1,
	// Audio
	RK_CODEC_TYPE_MP3,
	RK_CODEC_TYPE_MP2,
	RK_CODEC_TYPE_G711A,
	RK_CODEC_TYPE_G711U,
	RK_CODEC_TYPE_G726,
	// Video
	RK_CODEC_TYPE_H264,
	RK_CODEC_TYPE_H265,
	RK_CODEC_TYPE_JPEG,
	RK_CODEC_TYPE_MJPEG,
	RK_CODEC_TYPE_NB
} CODEC_TYPE_E;

typedef enum rk_GET_LDCH_MODE_E {
	RK_NONE_LDCH = 0,
	RK_GET_LDCH_BY_FILE,
	RK_GET_LDCH_BY_BUFF
} GET_LDCH_MODE_E;

/*******************************************************
    structure define
*******************************************************/
typedef struct _rkMpiAICtx {
	int s32loopCount;
	AUDIO_DEV s32DevId;
	AI_CHN s32ChnId;
	RK_S32 s32ChnSampleRate;
	RK_S32 s32ChnCnt;
	RK_S32 s32PeriodCount;
	RK_S32 s32PeriodSize;
	RK_S32 s32DeviceChannel;
	RK_S32 s32DeviceSampleRate;
	RK_U32 s32BitWidth;
	
	RK_U32      s32DataReadEnable;
	RK_S32      s32SetVolumeCurve;
    RK_S32      s32SetVolume;
    RK_S32      s32SetMute;
    RK_S32      s32SetFadeRate;
    RK_S32      s32SetTrackMode;
    RK_S32      s32GetVolume;
    RK_S32      s32GetMute;
    RK_S32      s32GetTrackMode;

	RK_U32 AudioSize;
	RK_U32 AudioOffset;
    RK_S32      s32RecognizerEnable;
    RK_S32      s32AedEnable;
    RK_FLOAT      fSnrDB;
    RK_FLOAT      fLsdDB;
    RK_S32      s32BcdEnable;
    RK_S32      s32BuzEnable;
    RK_S32      s32GbsEnable;
    RK_S32      s32AedLoudCount;
    RK_S32      s32AedAcousticHighCount; // 高信噪比计数
    RK_S32      s32AedAcousticRecCountMax;// 录音高信噪最大值
    RK_S32      s32AedSaveRecCountMin;// 录音可以保存的最小值

    RK_S32      s32AedAcousticLowCount; // 低信噪比计数
	RK_S32      s32AedAcousticEndCountMax; // 静音多久结束识别
    RK_S32      s32AedAcousticMuteCountMax;// 静音低信噪最大值

    RK_S32      s32AedRecing;// 录音中
    RK_S32      s32BcdCount;
    RK_S32      s32BuzCount;
    RK_S32      s32GbsCount;
    RK_S32      s32VqeGapMs;
    RK_S32      s32VqeEnable;
    RK_S32      s32VqeResult;
    RK_S32      s32DumpAlgo;

    RK_S32      s32AedPolicy;
    RK_S32      s32GbsFrameLen;
    RK_S32      s32BcdFrameLen;
    RK_S32      s32BuzFrameLen;

    const char *pVqeCfgPath;
	AIO_ATTR_S stAiAttr;
	AUDIO_FRAME_S stFrame;
	RK_CHAR *dstFilePath;
	RK_CHAR *saveDataFile;
	RK_CHAR *cardName;
	RK_CHAR *AudioData;
} HET_AI_CTX_S;

typedef struct _rkMpiAOCtx {
	int s32loopCount;
	AUDIO_DEV s32DevId;
	RK_CHAR bBindAec;
	RK_CODEC_ID_E codeType;
	void *demuxerCfg;
	AI_CHN s32ChnId;
	RK_S32 s32ChnSampleRate;
	RK_S32 s32ChnCnt;
	RK_S32 s32PeriodCount;
	RK_S32 s32PeriodSize;
	RK_S32 s32DeviceChannel;
	RK_S32 s32DeviceSampleRate;
	RK_U32 s32BitWidth;
	RK_U32 s32DataReadEnable;
	RK_S32 s32SetVolumeCurve;
	RK_S32 s32SetVolume;
	RK_S32 s32SetMute;
	RK_U32 AudioSize;
	RK_U32 AudioOffset;
	AIO_ATTR_S stAoAttr;
	AUDIO_FRAME_S stFrame;

	
	RK_U32 s32SetTrackMode;
	
	RK_CHAR *dstFilePath;
	RK_CHAR *readDataFile;
	RK_CHAR *cardName;
	RK_CHAR *AudioData;
} HET_AO_CTX_S;
#define AMIX_MAX_NUM 26
typedef struct _rkMpiIOCtx {
	HET_AI_CTX_S ai;
	HET_AO_CTX_S ao;
	char* amix[AMIX_MAX_NUM][2];
} SAMPLE_MPI_CTX_S;

typedef struct {
    char *data;
    size_t size;
    char *audioData;
    size_t audioSize;
} MemoryStruct;

typedef struct {
    char *data;
    size_t size;
    RK_U32 clientId;
    RK_U32 SampleRate;
    RK_U64 timeStamp;
} MemoryAudio;

/**
 * 个人信息
 */
struct  person_key  {
	char *name;
	char *value;
};
struct  person_info  {
	struct  person_key keys[16];
};
/**
 * @brief 设置userId
 */
void update_user_id(char * userId);
/**
 * @brief 获取userId
 */
char *get_user_id(void);

RK_S32 apply_ai_aed(HET_AI_CTX_S *params) ;
/**
 * 
 */
static RK_S32 apply_ai_bcd(HET_AI_CTX_S *params);
/**
 * 
 */

static RK_S32 apply_ai_buz(HET_AI_CTX_S *params);
/**
 * @brief 创建音频通道 
 * @param ctx 音频通道参数
 * @return 成功返回0，失败返回-1
 */
static RK_S32 apply_ai_gbs(HET_AI_CTX_S *params);
/**
 * @brief 创建音频通道 
 * @param ctx 音频通道参数
 * @return 成功返回0，失败返回-1
 */
RK_S32 apply_ai_vqe(HET_AI_CTX_S *params);
int speechSynthesizerPutMp3(char *textStr);
int speechSynthesizerPut(char *textStr,char *saveStr);
int speechRecognizerPut(char *fileName,int autoGoto);
void *HET_AI_Get_Stream_Thread(void *pArgs) ;
void *HET_AO_Play_Stream_Thread(void * pArgs);
int split_audio(const int16_t *audio_data, size_t audio_length , int16_t data_width);
/**
 *  获取平台配置
 */
int clifeSmartProductMirrorGetconfig(void);
/**
 * 调用工具会话
 */
int clifeMicroAppToolChat(const char *query, int mode,int autoGoto);
/**
 * 调用会话配置
 */
int clifeSmartProductMirrorGetconfigStreamGetToken(void);
/**
 * 调用会话
 */
int clifeMicroAppChat(const char *query, int mode,int autoGoto);
/**
 * 创建会话
 */
int clifeSmartProductMirrorCreateSession(void);
int clifeSmartProductMirrorDeleteSession(char *ssesId);
void  calculate_init(void) ;
RK_S32 HET_AI_CreateChn(HET_AI_CTX_S *params);
RK_S32 HET_AI_DestroyChn(HET_AI_CTX_S *ctx);
extern RK_BOOL global_run;
extern RK_U32 ai_run,rec_ready;
extern RK_BOOL ao_run;
extern RK_BOOL in_play;
extern RK_BOOL in_asr;
extern RK_BOOL in_tts;
extern RK_BOOL in_query;
extern RK_BOOL in_oath;
RK_S32 het_adec_audio(RK_CHAR *pInPath);

RK_BOOL get_chat_stat();
void setAppkey(char *appkey);
void setAkId(char *akId);
void setAkSecret(char *akSecret);
void setToken(char *token);
void setTokenDomain(char *tokenDomain);
void setApiVersion(char *vipServerDomain);
void setUrl(char *url);
void setVipServerDomain(char *vipServerDomain);
void setVipServerTargetDomain(char *vipServerTargetDomain);
void setAudioPath(char *audioPath);
void setVoice(char *voice);
int speechRecognizer(char *fileName);
int speechSynthesizer(char *textStr);
void nls_recognizer_clean(void);
char* het_ai_has_rec();
void het_ai_clean_rec();
void clife_agent_clean(void);
int rkchatgpt_init(void);
uint8_t * readFile(const char *filename , size_t  *size);

RK_S32 apply_ai_aed(HET_AI_CTX_S *params);
void het_ai_apply();
// url 请求
/**
 * @brief 缓存返回音频数据
 */
size_t audioPlayBuf_write_callback(void *ptr, size_t size, size_t nmemb, void *userdata);
/**
 * @brief 缓存返回数据
 */
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *userdata);
/**
 * @brief 设置token
 */
void update_ali_token(char * token);
/**
 * @brief 设置appKey
 */
void update_ali_appKey(char * key);
/**
 * @brief 设置声音模型
 */
void update_ali_voice(char * voice);
/**
 * @brief 设置执行超时时间
 */
void update_ali_expireTime(long expireTime);
/**
 * @brief 设置音频采样率
 */
void update_ali_sampleRate(int sampleRate);
/**
 * @brief 设置音频音量
 */
void update_ali_volume(int volume);
/**
 * @brief 设置音频pitchRate
 */
void update_ali_pitchRate(int pitchRate);
/**
 * @brief 设置音频speechRate
 */
void update_ali_speechRate(int speechRate);
/**
 * @brief 设置mac
 */
void update_clife_mac(char * mac);
/**
 * @brief 设置配置url
 */
void update_clife_config_url(char * url);
/**
 * @brief 设置配置token
 */
void update_clife_config_token(char * token);

/**
 * @brief 设置智能体url
 */
void update_clife_agent_url(char * url);
/**
 * @brief 设置智能体token
 */
void update_clife_agent_token(char * token);
/**
 * @brief 设置智能体appid
 */
void update_clife_agent_appid(int id);
/**
 * @brief 设置智能体会话ID
 */
void update_clife_agent_sessionId(char * id);
char * get_clife_agent_sessionId(void);
/**
 * @brief 获取识别返回结果
 */
char * nls_recognizer_get(void);
/**
 * @brief 获取openAI返回结果
 */
char * nls_openai_get(void);
/**
 * @brief 获取智能体返回结果
 */
char * clife_agent_get(void);
void update_chat_cloud(int id);
int get_chat_cloud(void);
void update_openai_key(char * key);
void update_openai_url(char * url);
void update_openai_model(char * model);
void update_openai_clean(void);
// 音频控制
/**
 * 获取当前播放状态
 */
RK_BOOL get_sound_out_stat();
//  交互命令
/**
 * @brief 播放音频文件
 * @param argc 参数个数
 * @param argv 参数列表 start stop filename
 */
int rkchatgpt_play(int argc, char *argv[]);
/**
 * @brief 录音保存到文件
 * @param argc 参数个数
 * @param argv 参数列表 start stop filename
 */
int rkchatgpt_record(int argc, char *argv[]);
/**
 * @brief 播放音频数据
 * @param argc 参数个数
 * @param argv 参数列表 filename
 */
int rkchatgpt_sendaudio(int argc, char *argv[]);
/**
 * @brief 设置双mic模式
 * @param argc 参数个数
 * @param argv 参数列表
 */
int rkchatgpt_dualmic(int argc, char *argv[]);
/**
 * @brief 设置回采模式
 * @param argc 参数个数
 * @param argv 参数列表
 */
int rkchatgpt_enveq(int argc, char *argv[]);
/**
 * @brief 调用tts
 * @param argc 参数个数
 * @param argv 参数列表 filename
 */
// 声音转文本 filename
int rkchatgpt_tts(int argc, char *argv[]);
/**
 * @brief 调用asr
 * @param argc 参数个数
 * @param argv 参数列表 filename
 */
// 文本转声音 filename
int rkchatgpt_asr(int argc, char *argv[]);
/**
 * @brief 调用大模型
 * @param argc 参数个数
 * @param argv 参数列表 filename
 */
// 请求openai apikey token filename
int rkchatgpt_openai(int argc, char *argv[]);
/**
 * @brief 识别音频
 * @param argc 参数个数
 * @param argv 参数列表 filename
 */
int rkchatgpt_recognizer(int argc, char *argv[]);

/**
 * @brief 设置音量
 * @param params 音频参数
 * @return 成功返回0，失败返回-1
 */
RK_S32 HET_AI_apply_Volume(int volume);
/**
 * @brief 设置静量
 * @param params 音频参数
 * @return 成功返回0，失败返回-1
 */
RK_S32 HET_AI_apply_Mute(int s32SetMute);
/**
 * @brief 设置音量
 * @param params 音频参数
 * @return 成功返回0，失败返回-1
 */
RK_S32 HET_AO_apply_Volume(int volume);
/**
 * @brief 设置静量
 * @param params 音频参数
 * @return 成功返回0，失败返回-1
 */
RK_S32 HET_AO_apply_Mute(int s32SetMute);
// 命令行接口
typedef struct {
	const char *cmd;
	const char *desc;
	int (*exec)(int argc, char *argv[]);
} command_t;
int rk_cmd_cli(int argc, char *argv[]);
void *rk_cmd_server_command_func(void *arg);
void cmd_exit();
int openaiPut(char * textStr,int autoGoto);
/**
 * @brief 个人信息
*/
struct  person_key *findPersonKey(char * key);
//ipc 接口
#define MSG_KEY 7918
#define MSG_TYPE_PLAY 1
#define MSG_TYPE_RECORD 2
#define MSG_TYPE_SENDAUDIO 3
#define MSG_TYPE_DUALMIC 4
#define MSG_TYPE_ENVEQ 5
#define MSG_TYPE_TTS 6
#define MSG_TYPE_ASR 7
#define MSG_TYPE_OPENAI 8
#define MSG_TYPE_REECOGNIZER 9

typedef struct {
    long msg_type;
    char cmd[256];
} audio_msg_t;
int send_quit_request(long type,const char *cmdData);
RK_S32 het_ao_init(HET_AO_CTX_S *ctx);
RK_S32 het_ao_deinit(HET_AO_CTX_S *ctx);
int clifeSmartProductMirrorGetconfigStreamGetToken(void);
extern SAMPLE_MPI_CTX_S g_ctx;
extern pthread_mutex_t curl_agent_lock;
extern pthread_mutex_t curl_buf_lock;
extern pthread_mutex_t play_lock;
extern pthread_mutex_t curl_lock;
extern pthread_mutex_t token_lock;
extern struct  person_info g_personInfo;
#define HET_LOGI clogi
#define HET_LOGD clogd
#define HET_LOGW clogw
#define HET_LOGE cloge
#ifdef __cplusplus
}
#endif
#endif
